import React, { forwardRef, useState, useCallback, useRef, useEffect } from 'react';
import styled from 'styled-components';
import { Button, Space, Slider } from 'antd';
import { ZoomInOutlined, ZoomOutOutlined } from '@ant-design/icons';
import { WineItem } from './WineItem';
import type { WineMenuConfig, WineItem as WineItemType } from '../types';
import './WineMenuCanvas.css';

interface WineMenuCanvasProps {
  config: WineMenuConfig;
  wineItems: WineItemType[];
  onItemEdit?: (item: WineItemType) => void;
  onItemDelete?: (item: WineItemType) => void;
}

const PreviewContainer = styled.div`
  position: relative;
  width: 100%;
  height: 800px;
  overflow: hidden;
  background: #f0f0f0;
  user-select: none;
  display: flex;
  align-items: center;
  justify-content: center;
`;

const DraggableContainer = styled.div<{ scale: number; x: number; y: number }>`
  position: absolute;
  transform: translate(${props => props.x}px, ${props => props.y}px) scale(${props => props.scale});
  transform-origin: center center;
  cursor: grab;
  &:active {
    cursor: grabbing;
  }
`;

const CanvasContainer = styled.div<{ config: WineMenuConfig }>`
  min-width: ${props => props.config.layout.width}px;
  height: ${props => props.config.layout.height}px;
  padding: ${props => props.config.layout.containerPadding}px;
  background-color: ${props => props.config.background.color};
  background-image: ${props => props.config.background.image ? `url(${props.config.background.image})` : 'none'};
  background-size: cover;
  background-position: center;
  position: relative;
  box-sizing: border-box;
`;

const FlexContainer = styled.div<{ config: WineMenuConfig }>`
  display: flex;
  flex-wrap: wrap;
  gap: ${props => props.config.layout.gap}px;
  width: 100%;
  height: 100%;
  padding: ${props => props.config.layout.padding}px;
  box-sizing: border-box;
`;

const ItemWrapper = styled.div<{ config: WineMenuConfig }>`
  height: calc(${props => 100 / props.config.layout.rows}% - ${props => props.config.layout.gap * (props.config.layout.rows - 1) / props.config.layout.rows}px);
  box-sizing: border-box;
  flex: 1 0 calc(${props => 100 / props.config.layout.cols}% - ${props => props.config.layout.gap}px);
`;

const ControlsContainer = styled.div`
  position: absolute;
  bottom: 20px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 1;
  background: white;
  padding: 8px;
  border-radius: 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,0.15);
`;

export const WineMenuCanvas = forwardRef<HTMLDivElement, WineMenuCanvasProps>(
  ({ config, wineItems, onItemEdit, onItemDelete }, ref) => {
    const [scale, setScale] = useState(0.5);
    const [position, setPosition] = useState(() => ({
      // 初始位置居中
      x: 0,
      y: 0
    }));
    const [isDragging, setIsDragging] = useState(false);
    const [dragStart, setDragStart] = useState({ x: 0, y: 0 });
    const previewRef = useRef<HTMLDivElement>(null);

    // 计算初始位置
    useEffect(() => {
      if (previewRef.current) {
        const previewRect = previewRef.current.getBoundingClientRect();
        const initialX = (previewRect.width - config.layout.width * scale) / 2;
        const initialY = (previewRect.height - config.layout.height * scale) / 2;
        setPosition({ x: initialX, y: initialY });
      }
    }, [scale, config.layout.width, config.layout.height]);

    // 根据布局计算最大商品数量
    const maxItems = config.layout.rows * config.layout.cols;
    // 取前N个商品
    const displayItems = wineItems.slice(0, maxItems);

    const handleMouseDown = useCallback((e: React.MouseEvent) => {
      e.preventDefault(); // 防止拖动时选中文本
      setIsDragging(true);
      setDragStart({
        x: e.clientX - position.x,
        y: e.clientY - position.y
      });
    }, [position]);

    const handleMouseMove = useCallback((e: React.MouseEvent) => {
      if (isDragging) {
        const newX = e.clientX - dragStart.x;
        const newY = e.clientY - dragStart.y;
        setPosition({
          x: newX,
          y: newY
        });
      }
    }, [isDragging, dragStart]);

    const handleMouseUp = useCallback(() => {
      setIsDragging(false);
    }, []);

    const handleZoom = (delta: number) => {
      setScale(prev => {
        const newScale = Math.min(Math.max(0.1, prev + delta), 2);
        return newScale;
      });
    };

    return (
      <PreviewContainer
        ref={previewRef}
        onMouseMove={handleMouseMove}
        onMouseUp={handleMouseUp}
        onMouseLeave={handleMouseUp}
      >
        <DraggableContainer
          ref={ref}
          scale={scale}
          x={position.x}
          y={position.y}
          onMouseDown={handleMouseDown}
        >
          <CanvasContainer config={config}>
            <FlexContainer config={config}>
              {displayItems.map((item) => (
                <ItemWrapper key={item.id} config={config}>
                  <WineItem
                    item={item}
                    config={config}
                    onEdit={() => onItemEdit?.(item)}
                    onDelete={() => onItemDelete?.(item)}
                  />
                </ItemWrapper>
              ))}
            </FlexContainer>
          </CanvasContainer>
        </DraggableContainer>

        <ControlsContainer>
          <Space>
            <Button
              icon={<ZoomOutOutlined />}
              onClick={() => handleZoom(-0.1)}
              disabled={scale <= 0.1}
            />
            <Slider
              min={0.1}
              max={2}
              step={0.1}
              value={scale}
              onChange={setScale}
              style={{ width: 100 }}
            />
            <Button
              icon={<ZoomInOutlined />}
              onClick={() => handleZoom(0.1)}
              disabled={scale >= 2}
            />
          </Space>
        </ControlsContainer>
      </PreviewContainer>
    );
  }
);

WineMenuCanvas.displayName = 'WineMenuCanvas';

export default WineMenuCanvas; 